/**
 * customer控制器
 *
 * @author sxf
 * @email sxf02615@163.com
 * @date 2025/1/15
 */
package com.sxf.crm.controller;


import com.sxf.crm.entity.Contact;
import com.sxf.crm.service.ContactService;
import com.sxf.crm.service.DepartmentService;
import java.util.Set;
import com.sxf.crm.dto.ApproveRequest;
import com.sxf.crm.dto.CustomerDepartmentDTO;
import com.sxf.crm.dto.CustomerDepartmentRequest;
import com.sxf.crm.dto.CustomerDTO;
import com.sxf.crm.enums.CustomerStage;
import com.sxf.crm.exception.ResourceNotFoundException;
import com.sxf.crm.service.CustomerService;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;
import org.springframework.data.domain.PageImpl;

/**
 * REST controller for managing customer operations.
 * Provides endpoints for CRUD operations, department management, and approval workflows.
 */
@RestController
@RequestMapping("/api/customers")
@RequiredArgsConstructor
public class CustomerController {
    private static final Logger logger = LoggerFactory.getLogger(CustomerController.class);
    private final CustomerService customerService;
    private final ContactService contactService;
    private final DepartmentService departmentService;

    @GetMapping
    @PreAuthorize("hasAuthority('customer:list')")
    public ResponseEntity<Page<CustomerDTO>> getCustomers(
            @RequestParam(required = false) String name,
            @RequestParam(required = false) String stage,
            @RequestParam(required = false) String source,
            @RequestParam(required = false) String status,
            Pageable pageable) {
        
        CustomerStage customerStage = null;
        if (stage != null && !stage.trim().isEmpty()) {
            try {
                customerStage = CustomerStage.valueOf(stage);
            } catch (IllegalArgumentException e) {
                // 如果转换失败，保持为 null
            }
        }
        
        return ResponseEntity.ok(customerService.getCustomers(name, customerStage, source, status, pageable));
    }

    @PreAuthorize("hasAuthority('customer:view')")
    @GetMapping("/{id}")
    public ResponseEntity<CustomerDTO> getCustomer(@PathVariable Long id) {
        try {
            return ResponseEntity.ok(customerService.getCustomer(id));
        } catch (ResourceNotFoundException e) {
            return ResponseEntity.notFound().build();
        }
    }

    @PreAuthorize("hasAuthority('customer:view')")
    @GetMapping("/{id}/contacts")
    public ResponseEntity<Page<Contact>> getCustomerContacts(
            @PathVariable Long id,
            Pageable pageable,
            Authentication authentication) {
        
        // 获取当前用户的部门ID列表
        Set<Long> userDepartmentIds = departmentService.getUserDepartmentIds(authentication.getName());
        
        // 获取客户联系人
        Page<Contact> contactsPage = contactService.getCustomerContacts(id, pageable);
        
        // 过滤数据权限
        List<Contact> filteredContacts = contactsPage.getContent().stream()
            .filter(contact -> contact.getDepartments().stream()
                .anyMatch(d -> userDepartmentIds.contains(d.getId())))
            .collect(Collectors.toList());
            
        // 创建新的Page对象保持分页信息
        Page<Contact> filteredPage = new PageImpl<>(
            filteredContacts,
            pageable,
            contactsPage.getTotalElements());
            
        return ResponseEntity.ok(filteredPage);
    }

    @PreAuthorize("hasAuthority('customer:create')")
    @PostMapping
    public ResponseEntity<CustomerDTO> createCustomer(@RequestBody CustomerDTO customer) {
        return ResponseEntity.ok(customerService.createCustomer(customer));
    }

    @PreAuthorize("hasAuthority('customer:update')")
    @PutMapping("/{id}")
    public ResponseEntity<CustomerDTO> updateCustomer(@PathVariable Long id, @RequestBody CustomerDTO customer) {
        return ResponseEntity.ok(customerService.updateCustomer(id, customer));
    }

    @PreAuthorize("hasAuthority('customer:delete')")
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteCustomer(@PathVariable Long id) {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        logger.debug("Current user: {}, authorities: {}", 
            auth.getName(), 
            auth.getAuthorities());
            
        customerService.deleteCustomer(id);
        return ResponseEntity.ok().build();
    }

    @PreAuthorize("hasAuthority('customer:audit')")
    @PutMapping("/{id}/approve")
    public ResponseEntity<CustomerDTO> updateCustomerStatus(
            @PathVariable Long id,
            @RequestBody ApproveRequest request) {
        return ResponseEntity.ok(customerService.approveCustomer(id, request.isApproved(), request.getComment()));
    }

    @GetMapping("/{id}/departments")
    @PreAuthorize("hasAnyAuthority('customer:view', 'customer:list')")
    public ResponseEntity<List<CustomerDepartmentDTO>> getCustomerDepartments(@PathVariable Long id) {
        return ResponseEntity.ok(customerService.getCustomerDepartments(id));
    }

    @PostMapping("/{id}/departments")
    @PreAuthorize("hasAuthority('customer:edit')")
    public ResponseEntity<Void> addCustomerDepartment(
            @PathVariable Long id,
            @RequestBody CustomerDepartmentRequest request
    ) {
        customerService.addCustomerDepartment(id, request.getDepartmentId(), request.getSalesId());
        return ResponseEntity.ok().build();
    }

    @DeleteMapping("/{id}/departments/{departmentId}")
    @PreAuthorize("hasAuthority('customer:edit')")
    public ResponseEntity<Void> deleteCustomerDepartment(
            @PathVariable Long id,
            @PathVariable Long departmentId
    ) {
        customerService.deleteCustomerDepartment(id, departmentId);
        return ResponseEntity.ok().build();
    }

    @PreAuthorize("hasAuthority('customer:audit')")
    @PostMapping("/{id}/approve")
    public ResponseEntity<CustomerDTO> approveCustomer(
            @PathVariable Long id,
            @RequestBody ApproveRequest request
    ) {
        return ResponseEntity.ok(
            customerService.approveCustomer(id, request.isApproved(), request.getComment())
        );
    }

    @GetMapping("/search")
    @PreAuthorize("hasAuthority('customer:list')")
    public ResponseEntity<List<CustomerDTO>> searchCustomers(@RequestParam String query) {
        return ResponseEntity.ok(customerService.searchCustomers(query));
    }
}
